package IA;
import Grafico.*;
import Mundo.*;
import java.util.ArrayList;
import Personajes.*;
import Interfaz.*;
import java.io.Serializable;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author ADRIAN VARGAS
 */


public class IAL implements IA {

    Mapa map;
    ArrayList<Celda [][]> Mat_cel;
    ArrayList<int [][]> Mat_dec;
    Ejercito ej_amigo;
    Ejercito ej_enem;
    int num_cel;//celda en las cuales podra "ver" al enemigo
    Dibujador dibuja;

    public IAL(Mapa map, Ejercito ej_amigo, Ejercito ej_enem, Dibujador dibuja) {
        this.Mat_dec=new ArrayList();
        this.Mat_cel=new ArrayList();
        num_cel=12;
        this.map = map;
        this.ej_amigo = ej_amigo;
        this.ej_enem = ej_enem;
        this.dibuja=dibuja;
        for(int i=0;i<ej_amigo.getCant_batallones();i++){
            int matriz[][]=new int [2*num_cel+1][2*num_cel+1];
            for (int x=0;x<2*num_cel+1;x++)
                for (int y=0;y<2*num_cel+1;y++)
                    matriz[x][y]=0;
                Mat_dec.add(matriz);
                
        }        

        for(int i=0;i<ej_amigo.getCant_batallones();i++) actualiza_IA(i);
    }

    private void inicia_cel(int i){ // inicia las celdas segun su posicion inicial

        

            Celda matriz[][]=new Celda[2*num_cel+1][2*num_cel+1];

            int x_inic=ej_amigo.getBatallones().get(i).getX();
            int y_inic=ej_amigo.getBatallones().get(i).getY();


            for (int x=0;x<2*num_cel+1;x++)
                for (int y=0;y<2*num_cel+1;y++){

                    if ((x_inic-(num_cel+1)+x<0)||(x_inic-(num_cel+1)+x>=100)||(y_inic-(num_cel+1)+y<0)||(y_inic-(num_cel+1)+y>=154)){

                        matriz[x][y]=null;
                    }
                    else{
                        matriz[x][y]=map.celdas[y_inic-(num_cel+1)+y][x_inic-(num_cel+1)+x];//cuidado aca
                    }
                }
            if (this.Mat_cel.size()<=i) {
                this.Mat_cel.add(matriz);
            }
            else
                this.Mat_cel.set(i,matriz);

        
    }

    private void actualiza_IA(int i){

        inicia_cel(i);        

            for (int x=0;x<2*num_cel+1;x++)
                for (int y=0;y<2*num_cel+1;y++){

                    if(this.Mat_cel.get(i)[x][y]!=null && this.Mat_cel.get(i)[x][y].getElementoEnCelda()=='P'){

                        this.Mat_dec.get(i)[x][y]+=1000; // pongo +800 donde hay algun enemigo

                        int mat_temp[][]= new int[2*num_cel+1][2*num_cel+1];

                        mat_temp=llena_valores(mat_temp,this.Mat_cel.get(i),x,y); // se llena los demas valores

                        this.Mat_dec.set(i, mat_temp);

                        
                    }
                    
                }
    }

    public void decide_IA(Ventana_principal v){
        for (int i=0;i<ej_amigo.getCant_batallones();i++){

            if (!ej_amigo.getBatallones().get(i).isMuerto()){

                int x=ej_amigo.getBatallones().get(i).getX();
                int y=ej_amigo.getBatallones().get(i).getY();

                this.actualiza_IA(i);

                if (Mat_dec.get(i)[num_cel+1+1][num_cel+1]>0||Mat_dec.get(i)[num_cel+1-1][num_cel+1]>0||Mat_dec.get(i)[num_cel+1][num_cel+1+1]>0||Mat_dec.get(i)[num_cel+1][num_cel+1-1]>0){

                    //ver si hay alguien a atacar

                    //for(int t=0; t<1;t++){

                    Batallon enem;
                    x=ej_amigo.getBatallones().get(i).getX();
                    y=ej_amigo.getBatallones().get(i).getY();

                    if ((enem=this.busca_bat(ej_enem, x+1, y))!=null){

                      ej_amigo.ataca(ej_amigo.getBatallones().get(i), enem);
                      v.imprimeAtacado = true;
//                      v.update(v.getGraphics());
                      for(int z=0;z<ej_amigo.getCant_batallones();z++) actualiza_IA(z);
                      return;
                    }

                    if ((enem=this.busca_bat(ej_enem, x, y+1))!=null){

                      ej_amigo.ataca(ej_amigo.getBatallones().get(i), enem);
                      v.imprimeAtacado = true;
//                      v.update(v.getGraphics());
                      for(int z=0;z<ej_amigo.getCant_batallones();z++) actualiza_IA(z);
                      return;

                    }
                    if ((enem=this.busca_bat(ej_enem, x-1, y))!=null){
                      ej_amigo.ataca(ej_amigo.getBatallones().get(i), enem);
                      v.imprimeAtacado = true;
//                      v.update(v.getGraphics());
                      for(int z=0;z<ej_amigo.getCant_batallones();z++) actualiza_IA(z);
                      return;

                    }
                    if ((enem=this.busca_bat(ej_enem, x, y-1))!=null){

                      ej_amigo.ataca(ej_amigo.getBatallones().get(i), enem);
                      v.imprimeAtacado = true;
//                      v.update(v.getGraphics());
                      for(int z=0;z<ej_amigo.getCant_batallones();z++) actualiza_IA(z);
                      return;
                    }

                    int pos[]= new int[1];

                    this.actualiza_IA(i);

                    if (this.elige_mayor(this.Mat_dec.get(i), num_cel+1, num_cel+1, pos)>0){

                    //si hay ataca y luego actualizan todos
                    //si no, se mueve

                    if (pos[0]==1){//derecha

                        ej_amigo.getBatallones().get(i).mover(map, 1, 0);

                    }
                    if (pos[0]==2){//abajo

                        ej_amigo.getBatallones().get(i).mover(map, 0, 1);
                    }
                    if (pos[0]==3){//izquierda

                        ej_amigo.getBatallones().get(i).mover(map, -1, 0);
                    }
                    if (pos[0]==4){//arriba

                        ej_amigo.getBatallones().get(i).mover(map, 0, -1);
                    }

                    //y se actualiza i solo
                    //  }

                    this.dibuja.dibuja(map);
                    }
                    return;


                }

               this.actualiza_IA(i);

            }

        }

    }


    private int[][] llena_valores(int matriz[][],Celda mat_cel[][] ,int x_enem, int y_enem){

        int costo=-100;

        int mat_temp[][]= new int [2*num_cel+1][2*num_cel+1];

        for(int x=0; x<2*num_cel+1;x++)
            for(int y=0; y<2*num_cel+1;y++)
                mat_temp[x][y]= 0;

        //llenar firme
        mat_temp[x_enem][y_enem]=1000;//1000 al bat enemigo
        llena_temporal(mat_temp,x_enem,y_enem,costo);
        matriz=suma_matriz(matriz,mat_temp);

        //llenar con -1000 lo que no se pueda pasar

        matriz=cambiar_terreno(matriz,mat_cel);
        int matriz1[][]=matriz;

        return matriz;

    }

    private void llena_temporal(int matriz[][],int x_enem,int y_enem,int costo){
        int temp[]=new int[1];


        for (int i=x_enem+1; i<2*num_cel+1;i++){
            matriz[i][y_enem]=matriz[i-1][y_enem]+costo;
        }
        for (int i=y_enem+1; i<2*num_cel+1;i++){
            matriz[x_enem][i]=matriz[x_enem][i-1]+costo;
        }
        for (int i=x_enem-1; i>=0;i--){
            matriz[i][y_enem]=matriz[i+1][y_enem]+costo;
        }
        for (int i=y_enem-1; i>=0;i--){
            matriz[x_enem][i]=matriz[x_enem][i+1]+costo;
        }

        for (int x=x_enem+1;x<2*num_cel+1;x++)
            for (int y=y_enem+1;y<2*num_cel+1;y++)
                matriz[x][y]= elige_mayor(matriz, x,y,temp)+ costo;

        for (int x=x_enem+1;x<2*num_cel+1;x++)
            for (int y=y_enem-1;y>=0;y--)
                matriz[x][y]= elige_mayor(matriz, x,y,temp)+ costo;

        for (int x=x_enem-1;x>=0;x--)
            for (int y=y_enem+1;y<2*num_cel+1;y++)
                matriz[x][y]= elige_mayor(matriz, x,y,temp)+ costo;

        for (int x=x_enem-1;x>=0;x--)
            for (int y=y_enem-1;y>=0;y--)
                matriz[x][y]= elige_mayor(matriz, x,y,temp)+ costo;



//        int x_der=x_enem+1;
//        int x_izq=x_enem-1;
//        int y_inf=y_enem+1;
//        int y_sup=y_enem-1;
//        int temp[]=new int[1];
//
//        if (x_der<2*num_cel+1){
//
//            matriz[x_der][y_enem]= elige_mayor(matriz, x_der,y_enem,temp)+ costo;
//
//
//        }
//         if (y_sup>=0){
//
//            matriz[x_enem][y_sup]= elige_mayor(matriz, x_enem,y_sup,temp)+ costo;
//
//        }
//
//        if (x_izq>=0){
//
//            matriz[x_izq][y_enem]= elige_mayor(matriz, x_izq,y_enem,temp)+ costo;
//
//
//         }
//
//        if (y_inf<2*num_cel+1){
//
//            matriz[x_enem][y_inf]= elige_mayor(matriz, x_enem,y_inf,temp)+ costo;
//
//
//        }
//        if (y_inf<2*num_cel+1)llena_temporal(matriz, x_enem,y_inf,costo);
//        if (x_izq>=0)llena_temporal(matriz, x_izq,y_enem,costo);
//        if (y_sup>=0)llena_temporal(matriz, x_enem,y_sup,costo);
//        if (x_der<2*num_cel+1)llena_temporal(matriz, x_der,y_enem,costo);
    }

    private int elige_mayor(int matriz[][], int x, int y,int pos[]){

        int x_der=x+1;
        int x_izq=x-1;
        int y_inf=y+1;
        int y_sup=y-1;
        int a1=0;
        int a2=0;
        int a3=0;
        int a4=0;


        if (x_der<2*num_cel+1){

            a1=matriz[x_der][y];
            
        }

        if (y_inf<2*num_cel+1){

            a2=matriz[x][y_inf];
            
        }
        if (x_izq>=0){

            a3=matriz[x_izq][y];
            
        }
        if (y_sup>=0){

            a4=matriz[x][y_sup];
            
        }
        pos[0]=1;//derecha

        if(a1<a2){
            a1=a2;
            pos[0]=2;//abajo
        }
        if(a1<a3){
            a1=a3;
            pos[0]=3;//izquierda
        }

        if(a1<a4){
            a1=a4;
            pos[0]=4;//arriba
        }

        return a1;


    }

    private int[][] cambiar_terreno(int mat[][], Celda mat_cel[][]){

        for(int x=0; x<2*num_cel+1;x++)
            for(int y=0; y<2*num_cel+1;y++){
                if (mat_cel[x][y]==null||mat_cel[x][y].getTipoTerreno()=='.'||mat_cel[x][y].getTipoTerreno()=='E'||mat_cel[x][y].getTipoTerreno()=='a')
                    mat[x][y]=-1000;
                
                
            }
        return mat;

    }



    private int[][] suma_matriz(int mat1[][],int mat2[][]){

        int mat3[][]=new int[2*num_cel+1][2*num_cel+1];

        for(int x=0; x<2*num_cel+1;x++)
            for(int y=0; y<2*num_cel+1;y++)
                mat3[x][y]= mat1[x][y]+mat2[x][y];
        return mat3;

    }


    private Batallon busca_bat(Ejercito ejer, int x, int y){

        Batallon bat;

        for(int i=0;i<ejer.getCant_batallones();i++){

            bat=ejer.getBatallones().get(i);

            if(bat.getX()==x && bat.getY()==y) return bat;


        }
        return null;

    }

    @Override
    public void set_batobj(Batallon[] bat) {
        int i=1;
    }

}
